namespace IconPatcher
{
    using System;
    using System.Linq;

    using Microsoft.Win32;

    public static class VisualStudio2010
    {
        // http://stackoverflow.com/questions/1074411/how-to-open-a-wow64-registry-key-from-a-64-bit-net-application
        private static RegistryKey GetSoftwareRoot()
        {
            var path = IntPtr.Size == 8
                           ? @"Software\Wow6432Node"
                           : @"Software";
            return Registry.LocalMachine.OpenSubKey(path);
        }

        // http://blogs.msdn.com/b/heaths/archive/2010/05/04/detection-keys-for-net-framework-4-0-and-visual-studio-2010.aspx
        public enum Edition
        {
            Undefined = -1,
            IntShell = 0,
            PROCore = 1,
            VSTDCore = 2,
            VSTSCore = 3
        }

        public static Edition InstalledEdition()
        {
            var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\vs\Servicing\10.0");
            if (rootKey == null)
            {
                return Edition.Undefined;
            }

            var subkeys = rootKey.GetSubKeyNames()
                .OrderByDescending(x => x, StringComparer.OrdinalIgnoreCase);

            var names = Enum.GetNames(typeof(Edition));
            Array.Reverse(names); // this makes IntShell the last value checked

            foreach (var name in names)
            {
                if (subkeys.Contains(name, StringComparer.OrdinalIgnoreCase))
                {
                    return (Edition) Enum.Parse(typeof (Edition), name);
                }
            }

            return Edition.Undefined;
        }

        public static bool IsVersionInstalled(Edition edition)
        {
            try
            {
                var key = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0\" + edition);
                return key != null;
            }
            catch
            {
                return false;
            }
        }

        public static string PrimaryLanguage(Edition edition)
        {
            try
            {
                var rootKey = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\VS\Servicing\10.0\" + edition);
                if (rootKey == null)
                {
                    return null;
                }

                var keys = rootKey.GetSubKeyNames();
                if (keys.Length > 1)
                {
                    throw new Exception("There are multiple sub keys. Unable to determine the primary language.");
                }

                return keys[0];
            }
            catch
            {
                return null;
            }
        }

        public static string[] AllLanguages(Edition edition)
        {
            var languages = new[]
            {
                PrimaryLanguage(edition)
            };

            var languagePacks = GetSoftwareRoot().OpenSubKey(@"Microsoft\DevDiv\vs\Servicing\10.0\prolp");
            if (languagePacks != null && languagePacks.SubKeyCount != 0)
            {
                languages = languages.Concat(languagePacks.GetSubKeyNames()).ToArray();
            }

            return languages;
        }
    }
}